package models;

import java.util.*;

import org.codehaus.jackson.annotate.JsonTypeInfo;

@JsonTypeInfo(use=JsonTypeInfo.Id.MINIMAL_CLASS, include=JsonTypeInfo.As.PROPERTY)
public abstract class Tcard {
	
	private UUID id;
	private String author;
	private Date created;	
	private Date modified; 
	private Kind kind;    
	protected Status status;
	
	// Display Fields (Top):	
	protected int orderNo;	
	protected int personnelCount;
	protected String st_Unit;
	protected String LDW;
	protected String agency;
	protected String type; 	
	protected String displayId;
	
	// Display Fields (Card):
	protected String homeBase; 
	protected String departurePoint; 
	protected String destinationPoint;
	protected String ETD;
	protected String ETA;
	protected String remarks;
	protected Date ordered;		
	protected Date checkedIn;
	protected List<UpdateHistory> history;
	
	@SuppressWarnings("unused")
	private String kindLabel; // this is just a shortcut to get the printed string version of the Kind enum for serialization

	public Tcard(Kind kind, Status status)	{
		this.id = UUID.randomUUID();
		this.kind = kind;
		this.kindLabel = kind.toDisplayString();
		this.status = status;
		this.modified = new Date();
		this.created = new Date();	
		this.history = new LinkedList<UpdateHistory>();
	}
	
	public static Tcard createCard(Kind kind, Status status) {
		switch(kind) {
		case Aircraft:
			return new AircraftTcard(status);
		case Engines:
			return new EngineTcard(status);
		case HeavyEquipment:
			return new HeavyEquipmentTcard(status);
		case Generic:
			return new GenericTcard(status);
		case HandCrews:
			return new HandCrewTcard(status);
		case Helicopters: 
			return new HelicopterTcard(status);
		case Misc: 
			return new MiscTcard(status);
		case Personnel:
			return new PersonnelTcard(status);
		default:
			throw new RuntimeException("Error attempting to create Tcard for invalid Kind");
		}
	}
	
	public static Tcard createTestCard(Kind kind, Status status, String st_Unit, String type, String LDW, String agency, String id, String homeBase, String departurePoint, String ETD, String destinationPoint, String ETA)
	{
		Tcard tcard = createCard(kind, status);
		Random rand = new Random();
		
		tcard.author = "Smitherson";
		tcard.st_Unit = st_Unit;
		tcard.type = type;
		tcard.LDW = LDW;
		tcard.displayId = id;
		tcard.agency = agency;
		tcard.orderNo = rand.nextInt(10000);
		tcard.personnelCount = rand.nextInt(10);
		tcard.homeBase = homeBase;
		tcard.departurePoint = departurePoint;
		tcard.ETD = ETD;
		tcard.destinationPoint = destinationPoint;
		tcard.ETA = ETA;
		
		return tcard;
	}

	
	public String toDisplayString()
	{
		return st_Unit + '\n' + displayId;
	}

	public UUID getId() {
		return id;
	}
 	 
	public String getAuthor() {
		return author;
	}
	
	public void setAuthor(String value) {
		author = value;
		modified();
	}
	
	public Date getCreated() {
		return created;
	}

	public Date getModified() {
		return modified;
	}
	 	 
	public Kind getKind() {
		return kind;
	}

	public Status getStatus() {
		return status;
	}

	public void setStatus(Status status) {
		history.add(new UpdateHistory(this.status, status));
		this.status = status;
		modified();
	}
	
	public int getOrderNo() {
		return orderNo;
	}

	public void setOrderNo(int orderNo) {
		this.orderNo = orderNo;
		modified();
	}

	public int getPersonnelCount() {
		return personnelCount;
	}

	public void setPersonnelCount(int personnelCount) {
		this.personnelCount = personnelCount;
		modified();
	}

	public String getSt_Unit() {
		return st_Unit;
	}

	public void setSt_Unit(String st_Unit) {
		this.st_Unit = st_Unit;
		modified();
	}

	public String getLDW() {
		return LDW;
	}

	public void setLDW(String LDW) {
		this.LDW = LDW;
		modified();
	}

	public String getAgency() {
		return agency;
	}

	public void setAgency(String agency) {
		this.agency = agency;
		modified();
	}

	public String getType() {
		return type;
	}

	public void setType(String type) {
		this.type = type;
		modified();
	}

	public String getDisplayId() {
		return displayId;
	}

	public void setDisplayId(String displayId) {
		this.displayId = displayId;
		modified();
	}

	public String getHomeBase() {
		return homeBase;
	}

	public void setHomeBase(String homeBase) {
		this.homeBase = homeBase;
		modified();
	}

	public String getDeparturePoint() {
		return departurePoint;
	}

	public void setDeparturePoint(String departurePoint) {
		this.departurePoint = departurePoint;
		modified();
	}

	public String getDestinationPoint() {
		return destinationPoint;
	}

	public void setDestinationPoint(String destinationPoint) {
		this.destinationPoint = destinationPoint;
		modified();
	}

	public String getETD() {
		return ETD;
	}

	public void setETD(String ETD) {
		this.ETD = ETD;
		modified();
	}

	public String getETA() {
		return ETA;
	}

	public void setETA(String ETA) {
		this.ETA = ETA;
		modified();
	}

	public Date getCheckedIn() {
		return checkedIn;
	}

	public void setCheckedIn(Date checkedIn) {
		this.checkedIn = checkedIn;
		modified();
	}

	public Date getOrdered() {
		return ordered;
	}
	
	public void ordered() {
		this.ordered = new Date();
		modified();
	}
	
	public List<UpdateHistory> getHistory() {
		return history;
	}
	
	protected void modified() {
		this.modified = new Date();
	}

	public void setOrdered(Date dateValue) {
		this.ordered = dateValue;
		modified();
	}

	public void setRemarks(String textValue) {
		this.remarks = textValue;
		modified();
	}
	
	public String getRemarks() {
		return remarks;
	}
}
